//
//  CDCTWebService.m
//  ChronicDiseaseManager
//
//  Created by CDCT on 2017/10/17.
//  Copyright © 2017年 cdct. All rights reserved.
//

#import "SKBaseWebService.h"
#import "SKWebService.h"
#import "SKWebServiceErrorCode.h"
#import "AppAndDeviceTool.h"
#define SYNC_RESPONSE_MSG               @"message"
#define SYNC_RESPONSE_STATUS            @"status"
#define SYNC_RESPONSE_DATA              @"data"
#define SYNC_RESPONSE_CODE              @"code"

#define DIC_HAS_STRING(dic, key)  ([dic objectForKey:key] && [[dic objectForKey:key] isKindOfClass:[NSString class]])

#define DIC_HAS_NUMBER(dic, key)  ([dic objectForKey:key] && [[dic objectForKey:key] isKindOfClass:[NSNumber class]])

#define DIC_HAS_ARRAY(dic, key)  ([dic objectForKey:key] && [[dic objectForKey:key] isKindOfClass:[NSArray class]])

#define DIC_HAS_DIC(dic, key)  ([dic objectForKey:key] && [[dic objectForKey:key] isKindOfClass:[NSDictionary class]])

#define DIC_HAS_MEM(dic, key, className)  ([dic objectForKey:key] && [[dic objectForKey:key] isKindOfClass:[className class]])

#define DIC_MEM_NOT_NULL(dic, key) ([dic objectForKey:key] && ![[dic objectForKey:key] isKindOfClass:[NSNull class]])

#if DEBUG
// 测试
NSString * baseURLStr = @"https://wzgapi.repaimall.com";
NSString * liveSocketBaseUrl = @"ws://livews.dev.ec-cloudtech.com";
NSString * liveModuleBaseUrl = @"http://liveapi.dev.ec-cloudtech.com";
#else
//【业务】
NSString * baseURLStr = @"https://wzgapi.repaimall.com";
//【直播聊天】
NSString * liveSocketBaseUrl = @"wss://livews.repaimall.com";
//【直播业务】
NSString * liveModuleBaseUrl = @"https://liveapi.repaimall.com";
#endif


NSString * MainPath = @"";


static const NSArray<NSString *> *specialURLsArr;

@interface SKBaseWebService()

@end

@implementation SKBaseWebService

+ (SKWebService *)webService {
    SKWebService *webservice = [[SKWebService alloc] initWebServiceWithUserAgent:@"" deviceID:@""];
    return webservice;
}

#pragma mark - Core

+ (void)handleSuccess:(BOOL)isPost
                 path:(NSString*)path
           parameters:(NSDictionary*)parameters
            operation:(NSURLSessionDataTask *)op
                 json:(id)json
              success:(void (^)(ZCErrorCode status, NSString * msg, NSDictionary * data))success
              failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))failure
{
    
    [SKBaseWebService onResponseData:json
                             success:success
                             failure:failure];
}

+ (void)handleFailure:(BOOL)isPost
                 path:(NSString*)path
           parameters:(NSDictionary*)parameters
            operation:(NSURLSessionDataTask *)op
                error:(NSError*)error
              success:(void (^)(ZCErrorCode status, NSString * msg, NSDictionary * data))success
              failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))failure
{
    if([error.domain isEqualToString:@"NSURLErrorDomain"]
       && error.code == kHXSNetworkingCancelError)
    {//增加上传取消操作后的error code 判断
        failure(kHXSNetworkingCancelError, @"网络请求取消", nil);
        return;
    }
    failure(kHXSNetWorkError, @"网络错误", nil);
}


// MARK: - POST

+ (NSURLSessionDataTask *)postRequest:(NSString*)path
                           parameters:(id)parameters
                             progress:(void (^)(NSProgress * _Nonnull))uploadProgress
                              success:(void (^)(ZCErrorCode status, NSString * msg, NSDictionary * data))success
                              failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))failure

{
    [self configProjectPath];
    
    path = [MainPath stringByAppendingString:path];
    
    AppAndDeviceTool *tool = [AppAndDeviceTool shareInstance];
    [parameters setValue:tool.appVersionStr forKey:@"appVersion"];
    [parameters setValue:tool.appNameStr forKey:@"appName"];
    [parameters setValue:@"ios" forKey:@"systemType"];
    [parameters setValue:tool.deviceNameStr forKey:@"deviceName"];
    [parameters setValue:tool.connectionTypeStr forKey:@"connectionType"];
    [parameters setValue:tool.deviceIdStr forKey:@"deviceId"];
    [parameters setValue:tool.deviceModelStr forKey:@"deviceModel"];
    [parameters setValue:tool.deviceSystemVersionStr forKey:@"systemVersion"];
    [parameters setValue:@"iPhone" forKey:@"uiModel"];
    [parameters setValue:tool.channelStr forKey:@"channel"];
    [parameters setValue:tool.operatorStr forKey:@"operator"];
    [parameters setValue:tool.deviceTokenStr forKey:@"deviceToken"];
    
    NSString *baseURLStr = [SKBaseWebService selectBaseURLWithPath:path];
    parameters = [SKBaseWebService signDictionary:parameters];
    
    NSURLSessionDataTask *task = [[SKBaseWebService webService]
                                  postWithBaseUrl:baseURLStr
                                  path:path
                                  parameters:parameters
                                  progress:uploadProgress
                                  success:^(NSURLSessionDataTask *task, id responseObject) {
                                      [SKBaseWebService handleSuccess:YES
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                 json:responseObject
                                                              success:success
                                                              failure:failure];
                                  } failure:^(NSURLSessionDataTask *task, NSError *error) {
                                      [SKBaseWebService handleFailure:YES
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                error:error
                                                              success:success
                                                              failure:failure];
                                  }];
    
    
    return task;
}


#pragma mark - GET

+ (NSURLSessionDataTask *)getRequest:(NSString*)path
                          parameters:(NSDictionary*)parameters
                            progress:(void (^)(NSProgress * _Nonnull))downloadProgress
                             success:(void (^)(ZCErrorCode status, NSString * msg, NSDictionary * data))success
                             failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))failure
{
    [self configProjectPath];
    
    path = [MainPath stringByAppendingString:path];
    
    AppAndDeviceTool *tool = [AppAndDeviceTool shareInstance];
    [parameters setValue:tool.appVersionStr forKey:@"appVersion"];
    [parameters setValue:tool.appNameStr forKey:@"appName"];
    [parameters setValue:@"ios" forKey:@"systemType"];
    [parameters setValue:tool.deviceNameStr forKey:@"deviceName"];
    [parameters setValue:tool.connectionTypeStr forKey:@"connectionType"];
    [parameters setValue:tool.deviceIdStr forKey:@"deviceId"];
    [parameters setValue:tool.deviceModelStr forKey:@"deviceModel"];
    [parameters setValue:tool.deviceSystemVersionStr forKey:@"systemVersion"];
    [parameters setValue:@"iPhone" forKey:@"uiModel"];
//    [parameters setValue:tool.channelStr forKey:@"channel"];
    [parameters setValue:tool.operatorStr forKey:@"operator"];
    [parameters setValue:tool.deviceTokenStr forKey:@"deviceToken"];
    
    NSString *baseURLStr = [SKBaseWebService selectBaseURLWithPath:path];
    
    //    if ([SKBaseWebService containedUrl:path]) {
    //
    //        parameters = [SKBaseWebService signDictionary:parameters];
    //
    //        NSMutableDictionary *headerFieldMDic = [[NSMutableDictionary alloc] initWithCapacity:5];
    //        [headerFieldMDic setObject:[parameters objectForKey:@"device_id"] forKey:@"device_id"];
    //        [headerFieldMDic setObject:[parameters objectForKey:@"token"] forKey:@"token"];
    //        [headerFieldMDic setObject:[parameters objectForKey:@"time"] forKey:@"time"];
    //        [headerFieldMDic setObject:[parameters objectForKey:@"sign"] forKey:@"sign"];
    //
    //        [[SKBaseWebService webService] updateRequestSerializerHeadFieldWithDic:headerFieldMDic
    //                                                                     baseURL:baseURLStr];
    //
    //        [parameters setValue:nil forKey:@"device_id"];
    //
    //        [parameters setValue:nil forKey:@"token"];
    //
    //        [parameters setValue:nil forKey:@"time"];
    //
    //        [parameters setValue:nil forKey:@"sign"];
    //
    //    } else {
    //        parameters = [SKBaseWebService signDictionary:parameters];
    //    }
    
    NSURLSessionDataTask *task = [[SKBaseWebService webService]
                                  getWithBaseUrl:baseURLStr
                                  path:path
                                  parameters:parameters
                                  progress:downloadProgress
                                  success:^(NSURLSessionDataTask *task, id responseObject) {
                                      [SKBaseWebService handleSuccess:NO
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                 json:responseObject
                                                              success:success
                                                              failure:failure];
                                  } failure:^(NSURLSessionDataTask *task, NSError *error) {
                                      
                                      
                                      [SKBaseWebService handleFailure:NO
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                error:error
                                                              success:success
                                                              failure:failure];
                                  }];
    
    return task;
}


#pragma mark - UPLOAD

+ (NSURLSessionDataTask *)uploadRequest:(NSString*)path
                             parameters:(NSDictionary*)parameters
                          formDataArray:(NSArray *)formDataArray
                               progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress
                                success:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary *data))success
                                failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary *data))failure
{
    [self configProjectPath];
    
    path = [MainPath stringByAppendingString:path];
    
    NSString *baseURLStr = [SKBaseWebService selectBaseURLWithPath:path];
    
    parameters = nil; // Don't send paramenter, If send parameters, the server returns error
    
    NSURLSessionDataTask *task = [[SKBaseWebService webService]
                                  uploadWithBaseUrl:baseURLStr
                                  path:path
                                  parameters:parameters
                                  formDataArray:formDataArray
                                  progress:uploadProgress
                                  success:^(NSURLSessionDataTask *task, id responseObject) {
                                      
                                      
                                      [SKBaseWebService handleSuccess:YES
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                 json:responseObject
                                                              success:success
                                                              failure:failure];
                                  } failure:^(NSURLSessionDataTask *task, NSError *error) {
                                      
                                      [SKBaseWebService handleFailure:YES
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                error:error
                                                              success:success
                                                              failure:failure];
                                  }];
    
    
    
    
    return task;
}



#pragma mark - PUT

+ (NSURLSessionDataTask *)putRequest:(NSString*)path
                          parameters:(NSDictionary*)parameters
                             success:(void (^)(ZCErrorCode status, NSString * msg, NSDictionary * data))success
                             failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))failure
{
    [self configProjectPath];
    
    path = [MainPath stringByAppendingString:path];
    
    NSString *baseURLStr = [SKBaseWebService selectBaseURLWithPath:path];
    
    parameters = [SKBaseWebService signDictionary:parameters];
    
    NSURLSessionDataTask *task = [[SKBaseWebService webService]
                                  putWithBaseUrl:baseURLStr
                                  path:path
                                  parameters:parameters
                                  success:^(NSURLSessionDataTask *task, id responseObject) {
                                      [SKBaseWebService handleSuccess:YES
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                 json:responseObject
                                                              success:success
                                                              failure:failure];
                                  } failure:^(NSURLSessionDataTask *task, NSError *error) {
                                      [SKBaseWebService handleFailure:YES
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                error:error
                                                              success:success
                                                              failure:failure];
                                  }];
    
    
    return task;
}


#pragma mark - DELETE

+ (NSURLSessionDataTask *)deleteRequest:(NSString*)path
                             parameters:(NSDictionary*)parameters
                                success:(void (^)(ZCErrorCode status, NSString * msg, NSDictionary * data))success
                                failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))failure
{
    [self configProjectPath];
    
    path = [MainPath stringByAppendingString:path];
    
    NSString *baseURLStr = [SKBaseWebService selectBaseURLWithPath:path];
    
    parameters = [SKBaseWebService signDictionary:parameters];
    
    NSURLSessionDataTask *task = [[SKBaseWebService webService]
                                  deleteWithBaseUrl:baseURLStr
                                  path:path
                                  parameters:parameters
                                  success:^(NSURLSessionDataTask *task, id responseObject) {
                                      [SKBaseWebService handleSuccess:YES
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                 json:responseObject
                                                              success:success
                                                              failure:failure];
                                  } failure:^(NSURLSessionDataTask *task, NSError *error) {
                                      [SKBaseWebService handleFailure:YES
                                                                 path:path
                                                           parameters:parameters
                                                            operation:task
                                                                error:error
                                                              success:success
                                                              failure:failure];
                                  }];
    
    return task;
}

// MARK: - THIRDURL
+ (NSURLSessionDataTask *)thirdRequest:(NSString *)path
                                  urls:(NSString *)url
                                  post:(BOOL)ispost
                            parameters:(NSDictionary*)parameters
                              progress:(void (^)(NSProgress * _Nonnull))downloadProgress
                               success:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))success
                               failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))failure {

    NSString *baseURLStr = url;
    parameters = [SKBaseWebService signDictionary:parameters];
    
    baseURLStr = [url stringByAppendingString:path];
    NSURLSessionDataTask *task = nil;
    if (ispost) {
        task = [[SKBaseWebService webService]
                postWithBaseUrl:baseURLStr
                path:path
                parameters:parameters
                progress:downloadProgress
                success:^(NSURLSessionDataTask *task, id responseObject) {
                    NSLog(@"+++++++++++++++++++++");
                    NSLog(@"%@",task.currentRequest.URL);
                    [SKBaseWebService handleSuccess:NO
                                               path:path
                                         parameters:parameters
                                          operation:task
                                               json:responseObject
                                            success:success
                                            failure:failure];
                } failure:^(NSURLSessionDataTask *task, NSError *error) {
                    
                    NSLog(@"+++++++++++++++++++++");
                    NSLog(@"%@",task.currentRequest.URL);
                    
                    [SKBaseWebService handleFailure:NO
                                               path:path
                                         parameters:parameters
                                          operation:task
                                              error:error
                                            success:success
                                            failure:failure];
                }];
        
    } else {
        task = [[SKBaseWebService webService]
                getWithBaseUrl:baseURLStr
                path:path
                parameters:parameters
                progress:downloadProgress
                success:^(NSURLSessionDataTask *task, id responseObject) {
                    [SKBaseWebService handleSuccess:NO
                                               path:path
                                         parameters:parameters
                                          operation:task
                                               json:responseObject
                                            success:success
                                            failure:failure];
                } failure:^(NSURLSessionDataTask *task, NSError *error) {
                    
                    
                    [SKBaseWebService handleFailure:NO
                                               path:path
                                         parameters:parameters
                                          operation:task
                                              error:error
                                            success:success
                                            failure:failure];
                }];
        
    }
    return task;
}


#pragma mark - Private Methods

+ (BOOL)containedUrl:(NSString *)urlString
{
    for (NSString *str in specialURLsArr) {
        if ([str isEqualToString:urlString]) {
            return YES;
        }
    }
    
    return NO;
}

+ (NSDictionary *)signDictionary:(NSDictionary *)dic
{
    return dic;
    //    签名操作
    //    if ((nil == dic)
    //        || [dic isKindOfClass:[NSDictionary class]]) {
    //        NSMutableDictionary *dicReal = [NSMutableDictionary dictionaryWithDictionary:dic];
    //        if (dicReal == nil) {
    //            dicReal = [NSMutableDictionary dictionary];
    //        }
    //
    //        //addtime
    //        NSString * timeStr = [NSString stringWithFormat:@"%.0f", [[NSDate date] timeIntervalSince1970]];
    //        [dicReal addEntriesFromDictionary:@{@"time":timeStr,
    //                                            SYNC_DEVICE_TYPE:@0,   //ios 0
    //                                            SYNC_APP_VERSION:@"szw",//[HXAppConfig sharedInstance].appVersion,
    //                                            @"protocol_version":@"2.0.0",
    //                                            SYNC_DEVICE_ID:@"szw"//[HXAppDeviceHelper uniqueDeviceIdentifier],
    //                                            }];
    //
    //        if ([dic objectForKey:SYNC_USER_TOKEN] == nil) {
    ////            NSString *tokenStr = [[HXSMediator sharedInstance] HXSMediator_token];
    //            NSString *tokenStr = @"szw";
    //            #warning szw dev
    ////            [dicReal setObjectExceptNil:tokenStr forKey:SYNC_USER_TOKEN];
    //            [dicReal setObject:@"szw" forKey:SYNC_USER_TOKEN];
    //        }
    //
    //        NSNumber *siteIDIntNum = @11111;//[[HXSMediator sharedInstance] HXSMediator_currentSiteID];
    //
    //        if ((nil != siteIDIntNum)
    //            && [dic objectForKey:SYNC_SITE_ID] == nil) {
    //            [dicReal setObject:siteIDIntNum
    //                        forKey:SYNC_SITE_ID];
    //        }
    //
    //        NSString * md5String = [SKBaseWebService calcSignStringWithArr:dicReal];
    //        [dicReal addEntriesFromDictionary:@{@"sign":md5String}];
    //
    //        return dicReal;
    //    } else {
    //        return [NSDictionary dictionary];
    //    }
}

+ (NSString *)calcSignStringWithArr:(NSDictionary *)dicReal
{
    NSMutableString *start = [[NSMutableString alloc] init];
    NSArray *keys = [dicReal allKeys];
    
    //keys按字母顺序排序
    keys = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
            {
                NSString * str1 = (NSString *)obj1;
                NSString * str2 = (NSString *)obj2;
                return [str1 compare:str2];
            }];
    for (NSString *key in keys) {
        [start appendFormat:@"%@=%@&", key, [dicReal objectForKey:key]];
    }
    
    //    [start appendFormat:@"%@", kHXSSecret];
    
    //    NSString * md5String = [NSString md5: start];
    //签名操作
    NSString *md5String = @"";
    
    return md5String;
}

+ (void)onResponseData:(id)responseObject
               success:(void (^)(ZCErrorCode status, NSString * msg, NSDictionary * data))success
               failure:(void (^)(ZCErrorCode status, NSString *msg, NSDictionary * data))failure
{
    id json = responseObject;
    // 解析json 与后台对接数据格式
    if(json && [json isKindOfClass:[NSDictionary class]]) {
        if (DIC_HAS_NUMBER(json, SYNC_RESPONSE_CODE)) {
            NSDictionary * data = [json objectForKey:SYNC_RESPONSE_DATA];
            id message = [json objectForKey:SYNC_RESPONSE_MSG];
            NSString * msg = [message isKindOfClass:[NSString class]] ? message : @"";
            NSInteger code = [[json valueForKey:@"code"] intValue];
            if (code == 302) {
                failure(kHXSNetworkingNeedLogin, msg, data);
            }else if (code == 403) {
                failure(kHXSInvalidTokenError, msg, data);
            } else if (code == 11002){
                failure(kHXSGoodsCheckError, msg, data);
            } else if (code == 500){
                failure(kHXSServerError, msg, data);
            } else if(code == 11010){
                failure(kHXSPaypassError, msg, data);
            } else if(code == 10002) {
                failure(kHXSShareQRCodeError, msg, data);
            } else if(code == 404) {
                failure(kHXSNetworkingNotFind, msg, data);
            } else {
                if(code == 0) {
                    success(kHXSNoError, msg, data);
                } else {
                    failure(kHXSNormalError, msg, data);
                }
            }
        } else {
            failure(kHXSUnknownError, @"未知错误-1001 code", nil);
        }
        
        
//        if(DIC_HAS_NUMBER(json, SYNC_RESPONSE_STATUS)) {
//            id message = [json objectForKey:SYNC_RESPONSE_MSG];
//            NSString * msg = [message isKindOfClass:[NSString class]] ? message : @"";
//            int status = [[json objectForKey:SYNC_RESPONSE_STATUS] intValue];
//            NSDictionary * data = [json objectForKey:SYNC_RESPONSE_DATA];
//            if ([data isKindOfClass:[NSNull class]]) {
//                data = @{};
//            }
//            if(status == kHXSNoError) {
//                if(!data) {
//                    data = [NSDictionary dictionary];
//                }
//                NSInteger code = [[json valueForKey:@"code"] intValue];
//                if (code == 10000) {
//                    failure(kHXSNetworkingNoDataError, msg, nil);
//                    return;
//                }
//                if (code == 403) {
//                    failure(kHXSInvalidTokenError, msg, data);
//                } else if (code == 11002){
//                    failure(kHXSGoodsCheckError, msg, data);
//                } else if (code == 500){
//                    failure(kHXSServerError, msg, data);
//                } else if(code == 11010){
//                    failure(kHXSPaypassError, msg, data);
//                } else if(code == 10002) {
//                    failure(kHXSShareQRCodeError, msg, data);
//                } else {
//                    if(code == 0) {
//                        success(status, msg, data);
//                    } else {
//                        failure(kHXSNormalError, msg, data);
//                    }
//                }
//            } else if (status == kHXSNormalError) {
//                failure(status, msg, data);
//            } else if(status == kHXSInvalidTokenError) {
//                //token error 单独处理
//                failure(status, msg, data);
//            }else if(msg != nil) {
//                failure(status, msg, data);
//            }else {
//                failure(kHXSUnknownError, @"未知错误-1000", data);
//            }
//        } else {
//            failure(kHXSUnknownError, @"未知错误-1001", nil);
//        }
    } else {
        failure(kHXSUnknownError, @"未知错误-1002 json", nil);
    }
}

+ (NSString *)webServiceCurrentDateString
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSDate *now = [[NSDate alloc] init];
    [dateFormatter setDateFormat:@"MM/dd/yyyy HH:mm:ss"];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    
    return [dateFormatter stringFromDate:now];
}

+ (NSString *)selectBaseURLWithPath:(NSString *)pathStr {
    //    NSString *configPath = [[NSBundle mainBundle] pathForResource:@"serverconfig" ofType:@"plist"];
    //    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:configPath];
    //    baseURLStr = [dict valueForKey:@"host"];
    //    MainPath = [dict valueForKey:@"path"];
    return [baseURLStr stringByAppendingString:pathStr];;
}

+ (void)configProjectPath {
    //    NSString *configPath = [[NSBundle mainBundle] pathForResource:@"serverconfig" ofType:@"plist"];
    //    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:configPath];
    //    MainPath = [dict valueForKey:@"path"];
}



@end
